<?php
define('TK_APP_TMPL',10);
define('TK_APP_EMPTY',11);
define('TK_ITEM_CONTROLLER_VIEW',15);
define('TK_ITEM_MODEL',16);
define('TK_ITEM_LOADER',17);
define('TK_ITEM_TABLE',18);
define('TK_ITEM_MODULE',19);
define('TKECHO',100);
define('TKWB',101);

function getProgramParams($argc, $argv) {
	$params = ($argc > 1) ? array_slice($argv,1) : false;
	return $params;
}

function initGlobals( $strPath ) {
	global $config, $apps;

	// Initializarea caii radacina a programului; 
	$length		= strrpos( $strPath , '\\' );
	$basePath 	= substr( $strPath, 0, $length );

	define('TK_BASEPATH',$basePath);
	define('DS',DIRECTORY_SEPARATOR);

	// Defineste calea spre fisierul de aplicatii (hard-code)
	define('TK_APP_DIR',	'Apps');
	define('TK_APP_PATH',	TK_BASEPATH . DS . TK_APP_DIR);
	
	// Oferim feedback in consola (indiferent de modul de rulare);
	// Utilizatorul putand astfel sa verifice daca nu sunt cele corecte;
	echo "\n> BasePath set to: ".TK_BASEPATH."\n";
	echo "> AppPath  set to: ".TK_APP_PATH."\n\n";

	// Defineste calea spre fisierele de configuratie,
	// care sunt citite si puse in variabile globale
	define('TK_XML_GLOBAL',	TK_BASEPATH . DS . 'Config' .DS . 'Global.xml');
	define('TK_XML_APPS',	TK_BASEPATH . DS . 'Config' .DS . 'Apps.xml');
	
	$config = loadXmlData( TK_XML_GLOBAL );
	$apps 	= loadXmlData( TK_XML_APPS );
}

function loadXmlData($xmlFile) {
	switch($xmlFile) {
		case TK_XML_GLOBAL:
			// Din fisierul global, vom avea nevoie doar de constante
			$xml 	= simplexml_load_file(TK_XML_GLOBAL);
			$config = array();
			foreach($xml->constants->const as $const) {
				$name 	= (String) $const['name'];
				$value 	= (String) $const['value'];
				$config[$name] = $value;
			}	unset($xml);
			return $config;
		case TK_XML_APPS:
			$apps = simplexml_load_file(TK_XML_APPS);
			return $apps;
	}
}



interface IToolkit 
{ 
	static function tkCreate($data, $type); 
}

class Toolkit implements IToolkit {
	static private $data;
	
	static function tkCreate($data,$type) {
		$data['name'] 	= ucfirst($data['name']);
		$data['prefix']	= ucfirst(@$data['prefix']); 

		self::$data = $data;
		switch( $type ) {
			case TK_APP_TMPL: 
				self::tkGenApp();
				break;
			case TK_APP_EMPTY: 
				self::tkGenApp(false);
				break;
			case TK_ITEM_CONTROLLER_VIEW:
			case TK_ITEM_MODEL:
			case TK_ITEM_TABLE:
			case TK_ITEM_MODULE:
			case TK_ITEM_LOADER:
				self::tkCreateItem($type);
				break;
		}
	}
	
	static function tkOut($msg) {
		static $mode=null;
		if(is_null($mode)){
			if(is_null($GLOBALS['winmain'])) $mode=TKECHO;
			else $mode=TKWB;
		}
		if($mode===TKWB) {
			global $controls;
			$txt = wb_get_text($controls['static'][TK_EDITREAD_02OUTP]);
			$txt .= $msg."\n";
			wb_set_text($controls['static'][TK_EDITREAD_02OUTP],$txt);
		} elseif($mode==TKECHO) {
			echo $msg."\n";
		}
	}
	
	function tkCreateFile($file, $content) {
		if(!file_exists($file)) {
			if(!empty($content)) {
				$succeded = file_put_contents($file, $content, LOCK_EX);
				if($succeded !== false) {
					$file = str_replace('\\','/',$file);
					self::tkOut($file." file created ok!..");
				} else { self::tkOut('> !! Could not write content to: '.$file); return false; }
			} else { self::tkOut('> !! No content to write in file: '.$file); return false; }
		} else { self::tkOut('> !! File already exists: '.$file); return false; }
		return true;
	}
	
	function tkCreateDir($dir, $mask = 777) {
		if(!is_dir($dir)) {
			$succeded = mkdir($dir, $mask);
			if( $succeded ) {
				$dir = str_replace('\\','/',$dir);
				self::tkOut($dir." folder created ok!!..");
			} else { self::tkOut('> !!! Could not create folder: '. $dir); return false; }
		} else { self::tkOut('> !!! Folder already exists: '. $dir); return false; }
		return true;
	}
	
	static function tkCreateItem($type) {
		global $apps, $config;
		// Luam prefixul aplicatiei
		$prefix = @self::$data['prefix'];			// In modul CLI acesta poate fi transmis ca parametru;
		if(empty($prefix)) {
			$prefix = "";
			foreach($apps->app as $app) {
				if(strtolower(self::$data['app']) == strtolower($app['name'])){
					$prefix = $app['prefix'];
				}
			}
		}
		//if file exists dont overwrite
		switch($type) {
			case TK_ITEM_CONTROLLER_VIEW:
				self::tkOut("-------Creating controller + view: ".self::$data['name']."-------");
				$item = file_get_contents('./items/controller.def');
				$item = str_replace('{#php}',"<?php",$item);
				$item = str_replace('{#name}',self::$data['name'],$item);
				$item = str_replace('{#prefix}',$prefix,$item);
				$file = TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_Controllers_Dir'].'/'.self::$data['name'].'.php';
				self::tkCreateFile($file, $item);

				//creating the view folders
				$dir = TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_Views_Dir'].'/'.self::$data['name'];
				self::tkCreateDir($dir);
				
				$dir = TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_Views_Dir'].'/'.self::$data['name'].'/layout';
				self::tkCreateDir($dir);

				
				//Creating the view
				$view = file_get_contents('./items/view.def');
				$view = str_replace('{#php}',"<?php",$view);
				$view = str_replace('{#name}',self::$data['name'],$view);
				$view = str_replace('{#prefix}',$prefix,$view);
				$file = TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_Views_Dir'].'/'.self::$data['name'].'/'.self::$data['name'].'.php'; 
				self::tkCreateFile($file, $view);

				//Creating the layout
				$layout = file_get_contents('./items/view.layout.def');
				$file = TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_Views_Dir'].'/'.self::$data['name'].'/layout/'.strtolower(self::$data['name']).'.phtml';
				self::tkCreateFile($file,$layout);
				break;
				
			case TK_ITEM_MODEL:
				self::tkOut("-------Creating model: ".self::$data['name']."-------");
				$model = file_get_contents('./items/model.def');
				$model = str_replace('{#php}',"<?php",$model);
				$model = str_replace('{#name}',self::$data['name'],$model);
				$model = str_replace('{#prefix}',$prefix,$model);
				$file = TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_Models_Dir'].'/'.self::$data['name'].'.php';
				self::tkCreateFile($file,$model);
				
				break;
			case TK_ITEM_TABLE:
				self::tkOut("-------Creating table: ".self::$data['name']."-------");
				$table = file_get_contents('./items/table.def');
				$table = str_replace('{#php}',"<?php",$table);
				$table = str_replace('{#name}',self::$data['name'],$table);
				$table = str_replace('{#prefix}',$prefix,$table);
				$dir = TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_Tables_Dir'];
				if(!is_dir($dir)) { self::tkCreateDir($dir); }
				
				$file = TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_Tables_Dir'].'/'.self::$data['name'].'.php';
				self::tkCreateFile($file, $table);

				break;
			case TK_ITEM_MODULE:
				self::tkOut("-------Creating module: ".self::$data['name']."-------");
				$dir = TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_Modules_Dir'];
				if(!is_dir($dir)) { self::tkCreateDir($dir); }

				$dir =  TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_Modules_Dir'].'/'.self::$data['name'];
				if(!is_dir($dir)) {
					self::tkCreateDir($dir);
					$module = file_get_contents('./items/module.def');
					$module = str_replace('{#php}',"<?php",$module);
					$module = str_replace('{#name}',self::$data['name'],$module);
					$module = str_replace('{#prefix}',$prefix,$module);
					$path = $dir.'/'.self::$data['name'].'.php';

					self::tkCreateFile($path,$module);
				} else { self::tkOut('> !!! Folder already exists: '.$dir); }
				
				break;
			case TK_ITEM_LOADER:
				self::tkOut("-------Creating loader for: ".self::$data['app']."-------");
				$loader = file_get_contents('./items/loader.def');
				$loader = str_replace('{#php}',"<?php",$loader);
				$loader = str_replace('{#prefix}',$prefix,$loader);

				$file = TK_APP_PATH.DS.self::$data['app'].'/'.$config['Default_Application_EntryPoint_Name'].'.php';
				
				self::tkCreateFile($file,$loader);
		}
	}
	
	static function tkGenApp($fromTemplate = true) {
		$isNewApp = self::tkCreateDirs();
		if($isNewApp) {
			self::tkAddToXML();
			self::tkOut("-------Started creating the file structure-------");
			self::tkCreateSetupXML();
			if($fromTemplate) {
				self::tkCreateLoader();
				self::tkCreateHandler();
				self::tkCreateView();
				self::tkCreateLanguage();
			}
			self::tkOut("-------".self::$data['name']." created successfully!-------");
		}
	}
	
	static function tkCreateSetupXML()
	{
		$dom = new DOMDocument();
		$dom->preserveWhiteSpace= false;
		$dom->formatOutput 		= true;
		
		//TODO: ordinea elementelor and such!!
		$appsetup = $dom->createElement('applicationSetup');
			$information = $dom->createElement('information');
				$information->setAttribute('name',self::$data['name']);
				$information->appendChild($dom->createElement('title',self::$data['name']));
				$information->appendChild($dom->createElement('description',@self::$data['desc']));
				$information->appendChild($dom->createElement('language',@self::$data['lang']));
				$information->appendChild($dom->createElement('keywords',@self::$data['keyw']));
				$information->appendChild($dom->createElement('template',@self::$data['tmpl']));
				$information->appendChild($dom->createElement('copyright',@self::$data['copy']));
				$information->appendChild($dom->createElement('date',@date('d/m/Y',time())));
				$information->appendChild($dom->createElement('version','1.0.0'));
			$appsetup->appendChild($information);
			$appsetup->appendChild($dom->createComment("\n# You can declare additional scripts or stylesheets\n# by sorrunding their location urls with <script> or\n# <stylesheet> tags placed inside the tags below"));
			$appsetup->appendChild($dom->createElement('scripts',''));
			$appsetup->appendChild($dom->createElement('stylesheets',''));
			$appsetup->appendChild($dom->createComment("\n# When using the database you need to edit these with\n# your actual database type, name and configuration"));
			$database = $dom->createElement('database');
				$database->setAttribute('name','your_database_name');
				$database->appendChild($dom->createElement('connection','mysql'));
				$database->appendChild($dom->createElement('host','localhost'));
				$database->appendChild($dom->createElement('user','root'));
				$database->appendChild($dom->createElement('password',''));
			$appsetup->appendChild($database);
		$dom->appendChild($appsetup);

		$xmlFile = TK_APP_PATH.DS.self::$data['name'].'/ApplicationSetup.xml';
		if(!file_exists($xmlFile)) {
			$dom->save($xmlFile);
			$xmlFile = str_replace('\\','/',$xmlFile);
			self::tkOut($xmlFile.' setup file created ok!!..');
		} else self::tkOut('> !!! A setup file already exists! Nothing changed..');
	}

	static function tkCreateDirs() {
		// Trebuie chemata prima data pentru a preveni generarea de fisiere
		// in cazul in care aplicatia deja exista;
		global $config;
		$app = self::$data['name'];
		
		if(!is_dir(TK_APP_PATH.DS.$app)) {
			self::tkOut("-------Started creating the directory structure-------");
			self::tkCreateDir(TK_APP_PATH.DS.$app);
			self::tkCreateDir(TK_APP_PATH.DS.$app.'/'.$config['Default_Application_Controllers_Dir']);
			self::tkCreateDir(TK_APP_PATH.DS.$app.'/'.$config['Default_Application_Views_Dir']);
			self::tkCreateDir(TK_APP_PATH.DS.$app.'/'.$config['Default_Application_Models_Dir']);
		} else {
			self::tkOut("> !!! ".$app." application already exists; nothing new created.\n");
			return false;
		}
		return true;
	}

	static function tkCreateLoader() {
		global $config;

		$tdata = file_get_contents('./tmpl/'.self::$data['app_tmpl'].'/loader.php');
		$tdata = str_replace('{#php}',"<?php",$tdata);
		$tdata = str_replace('{#prefix}',self::$data['prefix'],$tdata);
		$tdata = str_replace('{#appname}',self::$data['name'],$tdata);
		
		$file = TK_APP_PATH.DS.self::$data['name'].'/'.$config['Default_Application_EntryPoint_Name'].'.php';

		self::tkCreateFile($file,$tdata);
	}
	
	static function tkAddToXML()
	{
		global $apps;
		
		$item = new SimpleXMLElement($apps->asXML());
		$app = $item->addChild('app');
		$app->addAttribute('name',self::$data['name']);
		$app->addAttribute('prefix',self::$data['prefix']);
		$app->addChild('path','%AppRoot.'.self::$data['name']);
		$app->addChild('handler','Main');
		$app->addChild('config','ApplicationSetup')->addAttribute('format','xml');
		
		$dom = new DOMDocument();
		$dom->preserveWhiteSpace = false;
		$dom->formatOutput = true;
		$dom->loadXML($item->asXML());
		
		$appsXml = TK_BASEPATH.'/Config/Apps.xml';
		$dom->save($appsXml);
		
		$appsXml = str_replace('\\','/',$appsXml);
		self::tkOut($appsXml.' properly updated with '.self::$data['name'].'...');
	}
	
	static function tkCreateHandler() {
		global $config;
		
		//$handlerData = "<?php\nclass ".$prefix."_Controller_".$appname." extends Amfw_Controller\n{\n}";
		$tdata = file_get_contents('./tmpl/'.self::$data['app_tmpl'].'/handler.php');
		$tdata = str_replace('{#php}',"<?php",$tdata);
		$tdata = str_replace('{#prefix}',self::$data['prefix'],$tdata);
		
		$file = TK_APP_PATH.DS.self::$data['name'].'/'.$config['Default_Application_Controllers_Dir'].'/Main.php';
		
		self::tkCreateFile($file, $tdata);
	}
	
	static function tkCreateLanguage() {
		self::tkCreateDir(TK_APP_PATH.DS.self::$data['name'].'/Language');
		self::tkCreateDir(TK_APP_PATH.DS.self::$data['name'].'/Language/'.self::$data['lang']);
		
		$dom = new DOMDocument();
		$dom->preserveWhiteSpace= false;
		$dom->formatOutput 		= true;
		
		$local = $dom->createElement('localization');
		$local->setAttribute('language',self::$data['lang']);
		$local->setAttribute('application',self::$data['name']);
		$local->setAttribute('view','Main');
		$local->setAttribute('module','');
			$item = $dom->createElement('item','Your translation');
			$item->setAttribute('id','LOCALIZED_ID');
		$local->appendChild($dom->createComment("\n# Please see the Amfw_Translation class for more\n# details on implementing localization."));
		$local->appendChild($item);
		$dom->appendChild($local);

		$langXml = TK_APP_PATH.DS.self::$data['name'].'/Language/'.self::$data['lang'].'/'.self::$data['name'].'_Main.xml';
		$dom->save($langXml);
		
		$langXml = str_replace('\\','/',$langXml);
		self::tkOut($langXml." language file created ok!..");
	}
	
	static function tkCreateView() {
		global $config;
		// Creating the default view folders
		self::tkCreateDir(TK_APP_PATH.DS.self::$data['name'].'/'.$config['Default_Application_Views_Dir'].'/Main');
		self::tkCreateDir(TK_APP_PATH.DS.self::$data['name'].'/'.$config['Default_Application_Views_Dir'].'/Main/layout');
		
		// Creating the default view files
		$tmp = file_get_contents('./tmpl/'.self::$data['app_tmpl'].'/view.php');
		$tmp = str_replace('{#php}',"<?php",$tmp);
		$tmp = str_replace('{#prefix}',self::$data['prefix'],$tmp);
		self::tkCreateFile(TK_APP_PATH.DS.self::$data['name'].'/'.$config['Default_Application_Views_Dir'].'/Main/Main.php',$tmp);
		unset($tmp);

		$tmp = file_get_contents('./tmpl/blank/view.default.php');
		self::tkCreateFile(TK_APP_PATH.DS.self::$data['name'].'/'.$config['Default_Application_Views_Dir'].'/Main/layout/main.phtml',$tmp);
	}
}